package com.pudu.pudusclient;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

import com.DataProcess.CanData;
import com.DataProcess.CanDataProcess;
import com.DataProcess.ClientDataProcess;
import com.DataProcess.Robot;
import com.DataProcess.UIDataProcess;
import com.arithmetic.InitMap;
import com.arithmetic.InitNative;
import com.arithmetic.MotorsControl;
import com.arithmetic.SaveOut;
import com.arithmetic.StatusCheck;
import com.decode.Coding;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Administrator on 2016/8/9 0009.
 * modify by Cyc on 2016/8/31
 * 1.接收 can bus 数据，分析处理
 * 2.接收 wifi客户端数据，调制控制指令，发送到can bus
 *   canDataProcess -> 数据解码 -> 传感器DataProcess -> 公制单位 -> Robot
 *   ClientDataProcess -> 指令 -> Robot
 */


public class CanDataHandle {
    String thisLogTag = "CanDataHandle";
    HandlerThread mWorkThread;
    public Handler mHandler;
    CANDataService mcanBusService;

    static CanDataHandle mInstance;
    public  static CanDataHandle getInstance(CANDataService canBusService)
    {
        if(mInstance == null)
        {
            mInstance = new CanDataHandle(canBusService);
        }
        return mInstance;
    }

    private CanDataHandle(CANDataService canBusService){

        Log.i(thisLogTag,"debug start: CanDataHandle init");
        mcanBusService = canBusService;
        DataDealCallback mycallback = new DataDealCallback();
        mWorkThread = new HandlerThread("CanDataHandle");
        mWorkThread.start();
        mHandler = new Handler(mWorkThread.getLooper(), mycallback);

        InitMap.initMap();
        InitNative.initNative();

        initTimer();
        initTimerCheck();
    }

    public void Exit()
    {
        if(mWorkThread!= null )
        {
            Robot.isEnable = false;
            mcanBusService.write(new byte[] {0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00});
            Log.i(thisLogTag,"QUIT");
        }
    }

    public void dataFromCan(byte[] data)
    {
        if(mHandler != null)
        {
            Message msg = mHandler.obtainMessage();
            msg.what = 0x01;
            msg.obj = data;
            mHandler.sendMessage(msg);
        }
    }

    public void dataFromClient(byte[] data)
    {
        if(mHandler != null)
        {
            Message msg = mHandler.obtainMessage();
            msg.what = 0x02;
            msg.obj = data;
            mHandler.sendMessage(msg);
        }
    }

    //处理来自UI的动作data为Json格式： { "action": "ACTION_SMART_MOVE", "data":"2" } 对应对象为ActionMessage.java
    public void getControlFromUI(String data)
    {
        if(mHandler != null)
        {
            Message msg = mHandler.obtainMessage();
            msg.what = 0x03;
            msg.obj = data;
            mHandler.sendMessage(msg);
        }
    }

    Timer timerCheckReceive = new Timer();
    CanDataProcess canDataProcess = new CanDataProcess(timerCheckReceive);
    ClientDataProcess clientDataProcess = new ClientDataProcess();
    public class DataDealCallback implements Handler.Callback {
        @Override
        public boolean handleMessage(Message msg) {

            byte[] data;
            switch (msg.what) {
                case 0x1:
                    data = (byte[]) msg.obj;
                    canDataProcess.putOrigin(data);
                    canData.decode(data);
                    CanbusSave(canData);
                    break;
                case 0x2:
                    data = (byte[]) msg.obj;
                    clientDataProcess.putOrigin(data);
                    break;
                case 0x03:
                    String string = (String) msg.obj;
                    UIDataProcess.putOrigin(string);
                    break;
                case 0x04:
                    InitNative.setOpt();
                    Log.i(thisLogTag,"receive setting");
                    break;
            }
            return false;
        }
    }

    Timer timer;
    byte [] send2CAN = {0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00};

    Coding coding = new Coding();

    MotorsControl motorsControl = new MotorsControl();
    void initTimer(){
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                double[] target = new double[2];
                double adjust =  StatusCheck.checkObstacle();
                target[0] = Robot.targetSpeed[0] * adjust;
                target[1] = Robot.targetSpeed[1] * adjust;

                if(Math.abs(target[0])<0.05 && Math.abs(target[1])<0.05)
                    target = motorsControl.adjustTarget(target,true);
                else
                    target = motorsControl.adjustTarget(target,false);

                motorsControl.putTarget(target, Robot.speed, Robot.isCloseLoop);
                double[] out = motorsControl.getOutput();
                double[] pwm = SaveOut.getPWM(out);
                sendPWM2Can(pwm);     //下发控制指令
            }
        },0,100);
    }

    void sendPWM2Can(double[] pwm) {
        send2CAN = coding.speed((short)pwm[0],(short)pwm[1]);
        if ( mcanBusService != null)
            mcanBusService.write(send2CAN);
    }



    CanData canData = new CanData();
    public void CanbusSave(CanData data){
        try {
            Handler handler = CanbusDataSaveThread.getmHandler();
            if (handler != null) {
                Message msg = handler.obtainMessage();
                msg.what = 0x01;
                msg.obj = data;
                handler.sendMessage(msg);
            }
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    //**********业务逻辑部分***********************
    Timer timerCheck;
    void initTimerCheck(){
        timerCheck = new Timer();
        timerCheck.schedule(new TimerTask() {
            @Override
            public void run() {
                StatusCheck.checkSource();
                StatusCheck.checkMap();
                StatusCheck.checkTrack();
                StatusCheck.checkEnable();
                Log.i(thisLogTag,"timer current thread: "+Thread.currentThread().getId());
            }
        },0,100);
    }
    
}
